#include "DriverTesting.h"


UNICODE_STRING gDeviceName = RTL_CONSTANT_STRING(L"\\Device\\DriverTesting");
UNICODE_STRING gSymbolicLinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\Global\\DriverTesting");
PDEVICE_OBJECT gDeviceObject = NULL;

NTSTATUS DispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
	ULONG info = 0;
	UNREFERENCED_PARAMETER(DeviceObject);
	

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = info; 
	IoCompleteRequest(Irp,IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
	PIO_STACK_LOCATION stackLocation = IoGetCurrentIrpStackLocation(Irp);
	ULONG ioctl = stackLocation->Parameters.DeviceIoControl.IoControlCode;
	UNREFERENCED_PARAMETER(DeviceObject);

	DbgPrint("DeviceControlRoutine: code %X", ioctl);

	switch (ioctl) 
	{
	case IOCTL_GetSystemRootPath: 
		{ 
			DbgPrint("IOCTL_GetSystemRootPath");
            status = Test_GetSystemRootPath();

			break;
		}

	case IOCTL_GetHideList: 
		{
			DbgPrint("IOCTL_GetHideList");
            status = Run_All_Tests_GetHideList();
			
			break;
		}

	case IOCTL_ParserCharToUnicodeStr:
		{ 
			DbgPrint("IOCTL_ParserCharToUnicodeStr");
            status = Run_All_Tests_ParserCharToUnicodeStr();

			break;
		}

	case IOCTL_IsHideFile:  
		{ 
			DbgPrint("IOCTL_IsHideFile");
 			status = Run_All_Tests_IsHideFile();

			break;
		}

	default:
		{ 
			status = STATUS_INVALID_DEVICE_REQUEST;
			DbgPrint("STATUS_INVALID_DEVICE_REQUEST");
		}
	}

	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;
}

VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject)
{
	IoDeleteSymbolicLink(&gSymbolicLinkName);
	IoDeleteDevice(gDeviceObject);
}

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) 
{
	NTSTATUS status = STATUS_SUCCESS;

	DriverObject->DriverUnload = UnloadRoutine;
	DriverObject->MajorFunction[IRP_MJ_CREATE]         = DispatchCreateClose;
	DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DispatchCreateClose;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;

	status = IoCreateDevice(DriverObject, 0, &gDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &gDeviceObject);
	if(!NT_SUCCESS(status)) 
		return status; 

	SetFlag(gDeviceObject->Flags, DO_BUFFERED_IO);
	ClearFlag(gDeviceObject->Flags, DO_DEVICE_INITIALIZING);

	status = IoCreateSymbolicLink(&gSymbolicLinkName, &gDeviceName);

	if (!NT_SUCCESS(status)) 
		IoDeleteDevice(DriverObject);
	
	return status;
}